home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Programming / ace_gpl_release / src / ace / c / expr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-04  |  24.1 KB  |  1,102 lines

  1. /* << ACE >>
  2.  
  3.    -- Amiga BASIC Compiler --
  4.  
  5.    ** Parser: Expression code **
  6.    ** Copyright (C) 1998 David Benn
  7.    ** 
  8.    ** This program is free software; you can redistribute it and/or
  9.    ** modify it under the terms of the GNU General Public License
  10.    ** as published by the Free Software Foundation; either version 2
  11.    ** of the License, or (at your option) any later version.
  12.    **
  13.    ** This program is distributed in the hope that it will be useful,
  14.    ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.    ** GNU General Public License for more details.
  17.    **
  18.    ** You should have received a copy of the GNU General Public License
  19.    ** along with this program; if not, write to the Free Software
  20.    ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21.  
  22.    Author: David J Benn
  23.      Date: 26th October-30th November, 1st-13th December 1991,
  24.        14th,20th-27th January 1992, 
  25.            2nd-17th, 21st-29th February 1992, 
  26.        1st,13th,14th,22nd,23rd March 1992,
  27.        21st,22nd April 1992,
  28.        2nd,3rd,11th,15th,16th May 1992,
  29.        7th,8th,9th,11th,13th,14th,28th,29th,30th June 1992,
  30.        2nd-8th,14th-19th,26th-29th July 1992,
  31.        1st-3rd,7th,8th,9th August 1992,
  32.        6th,7th,21st December 1992,
  33.        28th February 1993,
  34.        12th June 1993,
  35.        12th,29th July 1994,
  36.        5th,6th November 1995
  37. */
  38.  
  39. #include "acedef.h"
  40.  
  41. /* externals */
  42. extern    int    sym;
  43. extern    int    factype;
  44. extern    int    negtype;
  45. extern    int    prodtype;
  46. extern    int    idivtype;
  47. extern    int    modtype;
  48. extern    int    simptype;
  49. extern    int    nottype;
  50. extern    int    andtype;
  51. extern    int    ortype;
  52. extern    int    eqvtype;
  53. extern    CODE    *curr_code;
  54. extern    int    labelcount;
  55. extern    char    tempstrname[80];
  56.  
  57. /* functions */
  58. BOOL coerce(typ1,typ2,cx)
  59. int  *typ1;
  60. int  *typ2;
  61. CODE *cx[];
  62. {
  63.  if ((*typ1 == stringtype) && (*typ2 != stringtype)) return(FALSE);
  64.  else
  65.  if ((*typ2 == stringtype) && (*typ1 != stringtype)) return(FALSE);
  66.  else
  67.  if (((*typ1 == shorttype) || (*typ1 == longtype)) && (*typ2 == singletype))
  68.  {
  69.   change_Flt(*typ1,cx);
  70.   *typ1=singletype;
  71.   return(TRUE);
  72.  }
  73.  else
  74.  if (((*typ2 == shorttype) || (*typ2 == longtype)) && (*typ1 == singletype))
  75.  {
  76.   gen_Flt(*typ2);
  77.   *typ2=singletype;
  78.   return(TRUE);
  79.  }
  80.  else
  81.  if ((*typ1 == shorttype) && (*typ2 == longtype)) 
  82.  {
  83.   change(cx[0],"move.w","(sp)+","d0");
  84.   change(cx[1],"ext.l","d0","  ");
  85.   change(cx[2],"move.l","d0","-(sp)");
  86.   *typ1=longtype;
  87.   return(TRUE);
  88.  }
  89.  else
  90.  if ((*typ2 == shorttype) && (*typ1 == longtype)) 
  91.  {
  92.   gen("move.w","(sp)+","d0");
  93.   gen("ext.l","d0","  ");
  94.   gen("move.l","d0","-(sp)");
  95.   *typ2=longtype;
  96.   return(TRUE);
  97.  }
  98.  else
  99.      return(TRUE); /* both shorttype, longtype or singletype OR notype! */
  100. }
  101.  
  102. void make_short()
  103. {
  104.  gen("move.l","(sp)+","d0");
  105.  gen("move.w","d0","-(sp)");
  106. }
  107.  
  108. void make_long()
  109. {
  110.  gen("move.w","(sp)+","d0");
  111.  gen("ext.l","d0","  ");
  112.  gen("move.l","d0","-(sp)");
  113. }
  114.  
  115. int ptr_term()
  116. {
  117. /* pointer operators -- higher precedence
  118.    than unary negation and exponentiation. */
  119.  
  120. int  localtype,op;
  121. BOOL dereference=FALSE;
  122.  
  123.   if (sym == shortpointer || sym == longpointer || sym == singlepointer)
  124.   {
  125.    op=sym;
  126.    dereference=TRUE;
  127.    insymbol();
  128.   }
  129.   
  130.   localtype=factor();
  131.  
  132.   if (dereference)
  133.   {
  134.    if (localtype != longtype)
  135.    {
  136.     _error(4);
  137.     localtype=undefined;
  138.    }
  139.    else
  140.    {
  141.     /* store address into a0 */
  142.     gen("move.l","(sp)+","a0");
  143.  
  144.     /* get value at address in a0 */    
  145.     switch(op)
  146.     {
  147.      /* *%<address> */    
  148.      case shortpointer : gen("move.w","(a0)","-(sp)");
  149.                   localtype=shorttype;
  150.                  break;
  151.  
  152.      /* *&<address> */    
  153.      case longpointer  : gen("move.l","(a0)","-(sp)");
  154.                  localtype=longtype;
  155.                  break;
  156.  
  157.      /* *!<address> */    
  158.      case singlepointer :gen("move.l","(a0)","-(sp)");
  159.                  localtype=singletype;
  160.                  break;
  161.     }
  162.    }
  163.   }
  164.   
  165.  return(localtype);
  166. }
  167.  
  168. int expterm()
  169. {
  170. /* exponentiation -> ALWAYS returns single */
  171. int  i;
  172. int  firsttype,original_firsttype,localtype,coercedtype;
  173. BOOL coercion;
  174. CODE *cx[5];
  175.  
  176.  firsttype=ptr_term();
  177.  localtype=firsttype;
  178.  
  179.  while (sym == raiseto)
  180.  {
  181.   if ((firsttype == shorttype) || (firsttype == longtype))
  182.   {
  183.    /* may need to coerce to singletype */
  184.    for (i=0;i<=4;i++)
  185.    {
  186.     gen("nop","  ","  ");
  187.     cx[i]=curr_code;
  188.    }
  189.   }
  190.  
  191.   insymbol();
  192.   factype=ptr_term();
  193.   if (factype == undefined) return(factype);
  194.   original_firsttype=firsttype; /* in case of SHORT->single coerce later */
  195.   coercion=coerce(&firsttype,&factype,cx);
  196.     
  197.   if (coercion)
  198.   {
  199.    coercedtype=factype;
  200.  
  201.    /* already singletype? */
  202.    if (coercedtype != singletype)
  203.    {
  204.     /* neither operands are singletype */ 
  205.     change_Flt(original_firsttype,cx); /* handles SHORT->single coerce */
  206.     gen_Flt(factype);
  207.    }
  208.  
  209.    gen("jsr","_power","  ");    /* - Call exponentiation function. */
  210.    gen("addq","#8","sp");    /* - Remove parameters from stack. */
  211.    gen("move.l","d0","-(sp)");  /* - Push the result. */
  212.                 
  213.    enter_XREF("_power");
  214.    enter_XREF("_MathTransBase"); /* opens FFP+IEEE SP transcendental libraries */
  215.  
  216.    localtype=singletype;  /* MUST always return a single-precision value
  217.                  because exponent might be -ve! */ 
  218.   } 
  219.   else _error(4); /* type mismatch */
  220.  
  221.   firsttype=localtype;  /* moving record of last sub-expression type */
  222.  }
  223.  return(localtype);
  224. }
  225.  
  226. int negterm()
  227. {
  228. int  localtype;
  229. BOOL negate=FALSE;
  230.  
  231.  /* unary negation? */
  232.  if (sym == minus) negate=TRUE;
  233.  if ((sym == minus) || (sym == plus)) insymbol();
  234.  
  235.  localtype=expterm();
  236.  if (localtype == undefined) return(localtype);
  237.  
  238.  if (negate)
  239.  {
  240.   switch(localtype)
  241.   {
  242.    case shorttype  : gen("neg.w","(sp)","  "); break;
  243.  
  244.    case longtype   : gen("neg.l","(sp)","  "); break;
  245.  
  246.    case singletype : gen("move.l","(sp)+","d0"); 
  247.        gen("move.l","_MathBase","a6");
  248.        gen("jsr","_LVOSPNeg(a6)","  ");
  249.        gen("move.l","d0","-(sp)");
  250.        enter_XREF("_MathBase");
  251.        enter_XREF("_LVOSPNeg");
  252.        break;
  253.    case stringtype : _error(4); break;
  254.   }
  255.  }
  256.  return(localtype);
  257. }
  258.  
  259. int prodterm()
  260. {
  261. /*
  262.    multiplication             -> returns long or single
  263.    floating-point division  -> returns single
  264. */
  265. int  op,i;
  266. int  firsttype,original_firsttype,localtype,coercedtype;
  267. BOOL coercion;
  268. CODE *cx[5];
  269.  
  270.  firsttype=negterm();
  271.  localtype=firsttype;
  272.  
  273.  while ((sym == multiply) || (sym == fdiv))
  274.  {
  275.   if ((firsttype == shorttype) || (firsttype == longtype))
  276.   {
  277.    /* may need to coerce to singletype or longtype */
  278.    for (i=0;i<=4;i++)
  279.    {
  280.     gen("nop","  ","  ");
  281.     cx[i]=curr_code;
  282.    }
  283.   }
  284.  
  285.   op=sym;  /* multiply or fdiv ? */
  286.  
  287.   insymbol();
  288.   negtype=negterm();
  289.  
  290.   if (negtype == undefined) return(negtype);
  291.  
  292.   /* save firsttype in case of a SHORT->single coercion 
  293.      later because coercion will need to start over again 
  294.      to avoid short->single code overwriting short->long code */
  295.  
  296.   original_firsttype=firsttype; 
  297.   coercion=coerce(&firsttype,&negtype,cx);
  298.     
  299.   /* if not stringtype, perform operation */
  300.   if (coercion) 
  301.   {
  302.    coercedtype=negtype;
  303.  
  304.    /* make sure operands are singletype if FFP division */
  305.    if ((op == fdiv) && (coercedtype != singletype))
  306.    {
  307.     /* neither operands are singletype 
  308.        -> both short or long */ 
  309.     change_Flt(original_firsttype,cx); /* handles SHORT->single correctly */
  310.     gen_Flt(negtype);
  311.     coercedtype=singletype;
  312.    }
  313.  
  314.    if ((op == multiply) && (coercedtype != longtype)) 
  315.       pop_operands(coercedtype);
  316.  
  317.    switch(op)
  318.    {
  319.     case multiply : switch(coercedtype)
  320.             {
  321.              case shorttype  :  gen("muls","d1","d0");
  322.                     localtype=longtype;
  323.                     break;
  324.             
  325.              case longtype   :    /* args on stack */
  326.                     gen("jsr","lmul","  "); 
  327.                     gen("add.l","#8","sp");
  328.                     enter_XREF("lmul");
  329.                     localtype=longtype;
  330.                     break;
  331.  
  332.              case singletype :  gen("movea.l","_MathBase","a6");
  333.                     gen("jsr","_LVOSPMul(a6)","  ");
  334.                     enter_XREF("_MathBase");
  335.                                enter_XREF("_LVOSPMul");
  336.                     localtype=singletype;
  337.                                break;
  338.             }
  339.             break;
  340.  
  341.     case fdiv     : gen("move.l","(sp)+","d1");  /* 2nd operand */
  342.             gen("move.l","(sp)+","d0");  /* 1st operand */
  343.             gen("movea.l","_MathBase","a6");
  344.             gen("jsr","_LVOSPDiv(a6)","  ");  
  345.             enter_XREF("_MathBase");
  346.                   enter_XREF("_LVOSPDiv");
  347.             localtype=singletype;
  348.                   break;
  349.    }
  350.  
  351.    push_result(localtype);  /* result */
  352.  
  353.   } 
  354.   else _error(4); /* notype -> type mismatch */
  355.  
  356.   firsttype=localtype;  /* moving record of last sub-expression type */
  357.  }
  358.  return(localtype);
  359. }
  360.  
  361. int idivterm()
  362. {
  363. /* integer division -- LONG = LONG \ LONG */
  364. int  i;
  365. int  firsttype,localtype;
  366. int  targettype=longtype;
  367. CODE *cx[5];
  368.  
  369.  firsttype=prodterm();
  370.  localtype=firsttype;
  371.  
  372.  while (sym == idiv) 
  373.  {
  374.   firsttype=make_integer(firsttype);  /* short or long -> 1st approximation */ 
  375.  
  376.   /* may need to coerce to long */
  377.   for (i=0;i<=2;i++)
  378.   {
  379.    gen("nop","  ","  ");
  380.    cx[i]=curr_code;
  381.   }
  382.  
  383.   if (firsttype == undefined) return(firsttype);
  384.  
  385.   coerce(&firsttype,&targettype,cx);  /* make sure it's a long dividend */
  386.   localtype=firsttype;
  387.  
  388.   insymbol();
  389.   prodtype=prodterm();
  390.   if (prodtype == undefined) return(prodtype); 
  391.   prodtype=make_integer(prodtype);  /* short or long at first */
  392.  
  393.   if ((firsttype != notype) && (prodtype != notype) &&
  394.       (firsttype != stringtype) && (prodtype != stringtype))
  395.   {
  396.    if (prodtype == shorttype) make_long();  /* ensure that divisor is LONG! */
  397.    prodtype=longtype;
  398.    localtype=prodtype;
  399.  
  400.    /* integer division - args on stack */
  401.    gen("jsr","ace_ldiv","  ");
  402.    gen("add.l","#8","sp");
  403.    gen("move.l","d0","-(sp)");
  404.    enter_XREF("ace_ldiv");
  405.   }
  406.   else _error(4); /* notype -> type mismatch */
  407.   firsttype=localtype;  /* moving record of last sub-expression type */
  408.  }
  409.  return(localtype);
  410. }
  411.  
  412. int modterm()
  413. {
  414. /* modulo arithmetic -> returns remainder of long integer or FFP division */
  415. int  i;
  416. int  firsttype,localtype;
  417. int  targettype=longtype;
  418. CODE *cx[5];
  419.  
  420.  firsttype=idivterm();
  421.  localtype=firsttype;
  422.  
  423.  while (sym == modsym) 
  424.  {
  425.   /* may need to coerce to single */
  426.   for (i=0;i<=4;i++)
  427.   {
  428.    gen("nop","  ","  ");
  429.    cx[i]=curr_code;
  430.   }
  431.  
  432.   if (firsttype == undefined) return(firsttype);
  433.  
  434.   insymbol();
  435.   idivtype=idivterm();
  436.  
  437.   if (idivtype == undefined) return(idivtype);
  438.  
  439.   /* perform integer or FFP modulo operation */
  440.   if ((firsttype != notype) && (idivtype != notype) &&
  441.       (firsttype != stringtype) && (idivtype != stringtype))
  442.   {
  443.    /* dividend (firsttype) is either short, long or single */
  444.  
  445.    if ((firsttype == singletype) || (idivtype == singletype))
  446.    {
  447.     /* single MOD */
  448.     coerce(&firsttype,&idivtype,cx);
  449.     /***************/
  450.    }
  451.    else 
  452.    {
  453.     /* integer MOD */
  454.     if (idivtype == shorttype)
  455.     {
  456.      make_long();  /* ensure that divisor is LONG! */
  457.      idivtype=longtype;
  458.     }
  459.     
  460.     if (firsttype == shorttype)
  461.        coerce(&firsttype,&targettype,cx);
  462.     /***************/
  463.    }
  464.  
  465.    localtype=idivtype;  /* short or single */
  466.  
  467.    if (localtype == longtype)
  468.    {
  469.     /* integer MOD - args on stack */
  470.     gen("jsr","ace_lrem","  ");
  471.     gen("add.l","#8","sp");
  472.     gen("move.l","d0","-(sp)");
  473.     enter_XREF("ace_lrem");
  474.    }
  475.    else
  476.    {
  477.     /* single MOD */
  478.     gen("move.l","(sp)+","d1");   /* divisor */
  479.     gen("move.l","(sp)+","d0");   /* dividend */
  480.     gen("jsr","_modffp","  ");
  481.     gen("move.l","d0","-(sp)");
  482.     enter_XREF("_modffp");
  483.     enter_XREF("_MathBase");
  484.     localtype=singletype;
  485.    }
  486.   }
  487.   else _error(4); /* notype -> type mismatch */
  488.   firsttype=localtype;  /* moving record of last sub-expression type */
  489.  }
  490.  return(localtype);
  491. }
  492.  
  493. int simple_expr()
  494. {
  495. int  op,i;
  496. int  firsttype,localtype;
  497. BOOL coercion;
  498. CODE *cx[5];
  499.  
  500.  firsttype=modterm();
  501.  localtype=firsttype;
  502.  
  503.  while ((sym == plus) || (sym == minus))
  504.  {
  505.   if ((firsttype == shorttype) || (firsttype == longtype))
  506.   {
  507.    /* may need to coerce */
  508.    for (i=0;i<=4;i++)
  509.    {
  510.     gen("nop","  ","  ");
  511.     cx[i]=curr_code;
  512.    }
  513.   }
  514.   op=sym;
  515.   insymbol();
  516.   modtype=modterm();
  517.   if (modtype == undefined) return(modtype);
  518.   coercion=coerce(&firsttype,&modtype,cx);
  519.   localtype=modtype;
  520.   if (coercion)
  521.   {
  522.    switch(op)
  523.    {
  524.     case plus :  if ((modtype != stringtype) && (modtype != shorttype))
  525.    {
  526.       gen("move.l","(sp)+","d1");
  527.     gen("move.l","(sp)+","d0");
  528.    }
  529.  
  530.    switch(modtype)
  531.    {
  532.     case shorttype  :     gen("move.w","(sp)+","d1");
  533.                   gen("move.w","(sp)+","d0");
  534.                     gen("add.w","d1","d0");
  535.                     break;
  536.  
  537.     case longtype   :    gen("add.l","d1","d0");
  538.                     break;
  539.  
  540.     case singletype :     gen("move.l","_MathBase","a6");
  541.                 gen("jsr","_LVOSPAdd(a6)","  ");
  542.                 enter_XREF("_LVOSPAdd");
  543.                 enter_XREF("_MathBase");
  544.                 break;
  545.  
  546.     case stringtype :     /* copy source to temp string */
  547.                 gen("move.l","(sp)+","a2"); /* 2nd */
  548.                 gen("move.l","(sp)+","a1"); /* 1st */
  549.             make_temp_string();
  550.                 gen("lea",tempstrname,"a0");
  551.                 gen("jsr","_strcpy","  ");
  552.                 /* prepare for strcat */
  553.                 gen("lea",tempstrname,"a0");
  554.                 gen("move.l","a2","a1");
  555.                 gen("jsr","_strcat","  ");
  556.                 gen("pea",tempstrname,"  ");
  557.                 enter_XREF("_strcpy");
  558.                 enter_XREF("_strcat");
  559.                 break;
  560.    }
  561.   
  562.    if (modtype == shorttype)
  563.             gen("move.w","d0","-(sp)");
  564.    else
  565.    if (modtype != stringtype)
  566.       gen("move.l","d0","-(sp)");
  567.                  break;
  568.  
  569.     case minus : if ((modtype != stringtype) && (modtype != shorttype))
  570.    {
  571.     gen("move.l","(sp)+","d1");
  572.     gen("move.l","(sp)+","d0");
  573.    }
  574.  
  575.    switch(modtype)
  576.    {
  577.     case shorttype  :     gen("move.w","(sp)+","d1");
  578.                     gen("move.w","(sp)+","d0");
  579.                 gen("sub.w","d1","d0");
  580.                     break;
  581.  
  582.     case longtype   :     gen("sub.l","d1","d0");
  583.                  break;
  584.  
  585.     case singletype :    gen("move.l","_MathBase","a6");
  586.                 gen("jsr","_LVOSPSub(a6)","  ");
  587.                    enter_XREF("_LVOSPSub");
  588.                 enter_XREF("_MathBase");
  589.                 break;
  590.  
  591.     case stringtype :     _error(4); break;
  592.   }
  593.   
  594.        if (modtype == shorttype)
  595.              gen("move.w","d0","-(sp)");
  596.        else
  597.            if (modtype != stringtype)
  598.               gen("move.l","d0","-(sp)");
  599.      }
  600.     } 
  601.     else _error(4); /* notype -> type mismatch */
  602.    firsttype=localtype;  /* moving record of last sub-expression type */
  603.   }
  604.  return(localtype);
  605. }
  606.  
  607. BOOL relop(op)
  608. int op;
  609. {
  610.  if ((op == equal) || (op == notequal) || (op == gtrthan) || 
  611.      (op == lessthan) || (op == gtorequal) || (op == ltorequal))
  612.      return(TRUE);
  613.  else
  614.      return(FALSE);
  615. }
  616.  
  617. char *cond_branch_op(op)
  618. int op;
  619. {
  620.  switch(op)
  621.  {
  622.   case equal     : return("beq.s");
  623.   case notequal  : return("bne.s");
  624.   case lessthan  : return("blt.s");
  625.   case gtrthan   : return("bgt.s");
  626.   case ltorequal : return("ble.s");
  627.   case gtorequal : return("bge.s");
  628.  }
  629. }
  630.  
  631. void make_label(name,lab)
  632. char *name;
  633. char *lab;
  634. {
  635. char num[40];
  636.  
  637.  strcpy(name,"_lab");
  638.  itoa(labelcount++,num,10);
  639.  strcat(name,num);
  640.  strcpy(lab,name);
  641.  strcat(lab,":\0");
  642.  
  643. int relexpr()
  644. {
  645. /* relational expression -> pass through this only ONCE */
  646. int  i,op=undefined;
  647. int  firsttype,localtype;
  648. char labname[80],lablabel[80],branch[6];
  649. BOOL coercion;
  650. CODE *cx[5];
  651.  
  652.  firsttype=simple_expr();
  653.  localtype=firsttype;
  654.  
  655.  if (relop(sym))
  656.  {
  657.   if ((firsttype == shorttype) || (firsttype == longtype))
  658.   {
  659.    /* may need to coerce */
  660.    for (i=0;i<=4;i++)
  661.    {
  662.     gen("nop","  ","  ");
  663.     cx[i]=curr_code;
  664.    }
  665.   }
  666.   op=sym;
  667.   insymbol();
  668.   simptype=simple_expr();
  669.   if (simptype == undefined) return(simptype);
  670.   coercion=coerce(&firsttype,&simptype,cx);
  671.   localtype=simptype;
  672.   if (coercion)
  673.   {
  674.    
  675.    /* compare on basis of type -> d5 = d0 op d1 */
  676.    switch(simptype)
  677.    {
  678.     case shorttype  :     gen("move.w","(sp)+","d1");  /* 2nd */
  679.                 gen("move.w","(sp)+","d0");  /* 1st */
  680.                 gen("moveq","#-1","d5");     /* assume true */
  681.                 gen("cmp.w","d1","d0");
  682.                 break;
  683.  
  684.     case longtype   :     gen("move.l","(sp)+","d1");  /* 2nd */
  685.                 gen("move.l","(sp)+","d0");  /* 1st */
  686.                 gen("moveq","#-1","d5");     /* assume true */
  687.                 gen("cmp.l","d1","d0");
  688.                 break;
  689.  
  690.     case singletype :     gen("move.l","(sp)+","d1");  /* 2nd */
  691.                 gen("move.l","(sp)+","d0");  /* 1st */
  692.                 gen("moveq","#-1","d5");     /* assume true */
  693.                 gen("move.l","_MathBase","a6");
  694.                 gen("jsr","_LVOSPCmp(a6)","  ");
  695.                 enter_XREF("_LVOSPCmp");
  696.                 enter_XREF("_MathBase");
  697.                 break;
  698.  
  699.     case stringtype :     gen("move.l","(sp)+","a1");  /* addr of 2nd string */
  700.             gen("move.l","(sp)+","a0");  /* addr of 1st string */
  701.             switch(op)
  702.             {
  703.              case equal     : gen("jsr","_streq","  ");
  704.                        enter_XREF("_streq");
  705.                       break;
  706.              case notequal  : gen("jsr","_strne","  ");
  707.                        enter_XREF("_strne");
  708.                       break;
  709.              case lessthan  : gen("jsr","_strlt","  ");
  710.                        enter_XREF("_strlt");
  711.                       break;
  712.              case gtrthan   : gen("jsr","_strgt","  ");
  713.                        enter_XREF("_strgt");
  714.                       break;
  715.              case ltorequal : gen("jsr","_strle","  ");
  716.                        enter_XREF("_strle");
  717.                       break;
  718.              case gtorequal : gen("jsr","_strge","  ");
  719.                        enter_XREF("_strge");
  720.                       break;
  721.             }
  722.             gen("move.l","d0","-(sp)"); /* push boolean result */
  723.             break;
  724.     }
  725.  
  726.     /* leave result on stack according to operator (-1 = true, 0 = false) */
  727.     /* (this code for short,long & single comparisons only) */
  728.     if (simptype != stringtype)
  729.     {    
  730.      make_label(labname,lablabel);
  731.      strcpy(branch,cond_branch_op(op));
  732.      gen(branch,labname,"  ");
  733.      gen("moveq","#0","d5"); /* not true */
  734.      gen(lablabel,"  ","  ");
  735.      gen("move.l","d5","-(sp)"); /* boolean result on stack */
  736.     }
  737.    } else _error(4);
  738.   }
  739.  
  740.  if (op == undefined) 
  741.     return(localtype);
  742.  else
  743.     return(longtype);  /* BOOLEAN! */  
  744. }
  745.  
  746. int notexpr()
  747. {
  748. int localtype,op;
  749.  
  750.  op=sym;
  751.  if (sym == notsym) insymbol();
  752.  
  753.  localtype=relexpr();
  754.  
  755.  if (op == notsym)
  756.  {
  757.   localtype=make_integer(localtype);
  758.   if (localtype == notype) return(localtype);
  759.   if (localtype == shorttype)
  760.    gen("not.w","(sp)","  ");
  761.   else
  762.    gen("not.l","(sp)","  ");
  763.  }
  764.  return(localtype);
  765. }
  766.   
  767. int andexpr()
  768. {
  769. int  op,i;
  770. int  firsttype,localtype;
  771. CODE *cx[5];
  772.  
  773.  firsttype=notexpr();
  774.  localtype=firsttype;
  775.  
  776.  if (sym == andsym)
  777.  {
  778.   firsttype=make_integer(firsttype);  
  779.   if (firsttype != notype)
  780.   {
  781.    while (sym == andsym)
  782.    {
  783.     if ((firsttype == shorttype) || (firsttype == longtype))
  784.     {
  785.      /* may need to coerce */
  786.      for (i=0;i<=4;i++)
  787.      {
  788.       gen("nop","  ","  ");
  789.       cx[i]=curr_code;
  790.      }
  791.     }
  792.     op=sym;
  793.     insymbol();
  794.     nottype=notexpr(); 
  795.     if (nottype == undefined) return(nottype);
  796.     nottype=make_integer(nottype);
  797.     coerce(&firsttype,¬type,cx);
  798.     localtype=nottype;
  799.     if (nottype != notype)
  800.     {
  801.      pop_operands(nottype);
  802.      if (nottype == shorttype) 
  803.      gen("and.w","d1","d0");
  804.      else
  805.      gen("and.l","d1","d0");
  806.      push_result(nottype);
  807.     } else _error(4);
  808.    }
  809.   } else _error(4);
  810.   firsttype=localtype;
  811.  }
  812.  return(localtype);
  813. }
  814.  
  815. int orexpr()
  816. {
  817. int  op,i;
  818. int  firsttype,localtype;
  819. CODE *cx[5];
  820.  
  821.  firsttype=andexpr();
  822.  localtype=firsttype;
  823.  
  824.  if ((sym == orsym) || (sym == xorsym))
  825.  {
  826.   firsttype=make_integer(firsttype);  
  827.   if (firsttype != notype)
  828.   {
  829.    while ((sym == orsym) || (sym == xorsym))
  830.    {
  831.    if ((firsttype == shorttype) || (firsttype == longtype))
  832.     {
  833.      /* may need to coerce */
  834.      for (i=0;i<=4;i++)
  835.      {
  836.       gen("nop","  ","  ");
  837.       cx[i]=curr_code;
  838.      }
  839.     }
  840.     op=sym;
  841.     insymbol();
  842.     andtype=andexpr();
  843.     if (andtype == undefined) return(andtype); 
  844.     andtype=make_integer(andtype);
  845.     coerce(&firsttype,&andtype,cx);
  846.     localtype=andtype;
  847.     if (andtype != notype)
  848.     {
  849.      pop_operands(andtype);  
  850.      switch(op)
  851.      {
  852.       case orsym  : if (andtype == shorttype)
  853.                gen("or.w","d1","d0");
  854.                     else
  855.                gen("or.l","d1","d0");
  856.                        break;
  857.  
  858.       case xorsym : if (andtype == shorttype)
  859.                   gen("eor.w","d1","d0");
  860.                   else
  861.                         gen("eor.l","d1","d0");
  862.                   break;
  863.      }
  864.      push_result(andtype);
  865.     } else _error(4);
  866.    }
  867.   } else _error(4);
  868.   firsttype=localtype;
  869.  }
  870.  return(localtype);
  871. }
  872.  
  873. int eqvexpr()
  874. {
  875. int  op,i;
  876. int  firsttype,localtype;
  877. CODE *cx[5];
  878.  
  879.  firsttype=orexpr();
  880.  localtype=firsttype;
  881.  
  882.  if (sym == eqvsym)
  883.  {
  884.   firsttype=make_integer(firsttype);  
  885.   if (firsttype != notype)
  886.   {
  887.    while (sym == eqvsym)
  888.    {
  889.    if ((firsttype == shorttype) || (firsttype == longtype))
  890.     {
  891.      /* may need to coerce */
  892.      for (i=0;i<=4;i++)
  893.      {
  894.       gen("nop","  ","  ");
  895.       cx[i]=curr_code;
  896.      }
  897.     }
  898.     op=sym;
  899.     insymbol();
  900.     ortype=orexpr(); 
  901.     if (ortype == undefined) return(ortype);
  902.     ortype=make_integer(ortype);
  903.     coerce(&firsttype,&ortype,cx);
  904.     localtype=ortype;
  905.     if (ortype != notype)
  906.     {
  907.      pop_operands(ortype);
  908.      if (ortype == shorttype) 
  909.      {
  910.          gen("jsr","_eqvw","  ");
  911.          enter_XREF("_eqvw");
  912.      }
  913.      else 
  914.        {
  915.          gen("jsr","_eqvl","  ");
  916.          enter_XREF("_eqvl");
  917.        }
  918.       push_result(ortype);
  919.     } else _error(4);
  920.    }
  921.   } else _error(4);
  922.   firsttype=localtype;
  923.  }
  924.  return(localtype);
  925. }
  926.  
  927. int expr()
  928. {
  929. int  op,i;
  930. int  firsttype,localtype;
  931. CODE *cx[5];
  932.  
  933.  firsttype=eqvexpr();
  934.  localtype=firsttype;
  935.  
  936.  if (sym == impsym)
  937.  {
  938.   firsttype=make_integer(firsttype);  
  939.   if (firsttype != notype)
  940.   {
  941.    while (sym == impsym)
  942.    {
  943.    if ((firsttype == shorttype) || (firsttype == longtype))
  944.    {
  945.      /* may need to coerce */
  946.      for (i=0;i<=4;i++)
  947.      {
  948.       gen("nop","  ","  ");
  949.       cx[i]=curr_code;
  950.      }
  951.     }
  952.     op=sym;
  953.     insymbol();
  954.     eqvtype=eqvexpr(); 
  955.     if (eqvtype == undefined) return(eqvtype);
  956.     eqvtype=make_integer(eqvtype);
  957.     coerce(&firsttype,&eqvtype,cx);
  958.     localtype=eqvtype;
  959.     if (eqvtype != notype)
  960.     {
  961.      pop_operands(eqvtype);
  962.      if (eqvtype == shorttype) 
  963.      {
  964.          gen("jsr","_impw","  ");
  965.          enter_XREF("_impw");
  966.      }
  967.      else 
  968.        {
  969.          gen("jsr","_impl","  ");
  970.          enter_XREF("_impl");
  971.        }
  972.      push_result(eqvtype);
  973.     } else _error(4);
  974.    }
  975.   } else _error(4);
  976.   firsttype=localtype;
  977.  }
  978.  return(localtype);
  979. }
  980.  
  981. void pop_operands(typ)
  982. int typ;
  983. {
  984.      if (typ == shorttype)
  985.      {
  986.       gen("move.w","(sp)+","d0");  /* 2nd operand */
  987.       gen("move.w","(sp)+","d1");  /* 1st operand -> d0 = d1 op d0 */
  988.      }
  989.      else
  990.      {  
  991.       gen("move.l","(sp)+","d0");  /* 2nd operand */
  992.       gen("move.l","(sp)+","d1");  /* 1st operand -> d0 = d1 op d0 */
  993.      } 
  994. }
  995.  
  996. void push_result(typ)
  997. int typ;
  998. {
  999.  if (typ == shorttype)
  1000.     gen("move.w","d0","-(sp)");
  1001.  else
  1002.     gen("move.l","d0","-(sp)");
  1003. }
  1004.  
  1005. void gen_round(type)
  1006. int type;
  1007. {  
  1008. /*
  1009. ** Convert float to integer
  1010. ** with rounding.
  1011. */
  1012.   gen("move.l","(sp)+","d0");
  1013.   gen("jsr","_round","  ");
  1014.   gen("move.l","d0","-(sp)");
  1015.   enter_XREF("_round");
  1016.   enter_XREF("_MathBase");
  1017.  
  1018.   /*
  1019.   ** Only relevant when called from
  1020.   ** assign_coerce() and STOREType=shorttype.
  1021.   */
  1022.   if (type == shorttype)
  1023.   {
  1024.    gen("move.l","(sp)+","d0");
  1025.    gen("move.w","d0","-(sp)");
  1026.   }
  1027. }  
  1028.  
  1029. void gen_Flt(typ)
  1030. int typ;
  1031. {
  1032. /* convert an integer to a single-precision float */
  1033.   if (typ == singletype) return;  /* already a float! */
  1034.  
  1035.   if (typ == stringtype) _error(4); /* can't do it */
  1036.  
  1037.   if (typ == shorttype)
  1038.      gen("move.w","(sp)+","d0");
  1039.   else
  1040.      gen("move.l","(sp)+","d0");
  1041.  
  1042.   if (typ == shorttype) gen("ext.l","d0","  "); /* extend sign */
  1043.  
  1044.   gen("move.l","_MathBase","a6");
  1045.   gen("jsr","_LVOSPFlt(a6)","  ");
  1046.   gen("move.l","d0","-(sp)");
  1047.   enter_XREF("_LVOSPFlt");
  1048.   enter_XREF("_MathBase");
  1049. }
  1050.  
  1051. void change_Flt(exptyp,cx)
  1052. int  exptyp;
  1053. CODE *cx[];
  1054. {
  1055. /* convert an integer to a float */
  1056.   if (exptyp == shorttype)
  1057.      change(cx[0],"move.w","(sp)+","d0");
  1058.   else
  1059.      change(cx[0],"move.l","(sp)+","d0");
  1060.   if (exptyp == shorttype) change(cx[1],"ext.l","d0","  ");
  1061.   change(cx[2],"move.l","_MathBase","a6");
  1062.   change(cx[3],"jsr","_LVOSPFlt(a6)","  ");
  1063.   change(cx[4],"move.l","d0","-(sp)");
  1064.   enter_XREF("_LVOSPFlt");
  1065.   enter_XREF("_MathBase");
  1066. }
  1067.  
  1068. int make_integer(oldtyp)
  1069. int oldtyp;
  1070. {
  1071.  if (oldtyp == stringtype) return(notype); /* can't do it! */
  1072.  else
  1073.  if (oldtyp == singletype) 
  1074.  { 
  1075.   gen_round(oldtyp);
  1076.   return(longtype); 
  1077.  }
  1078.  else
  1079.  return(oldtyp);  /* already an integer */
  1080. }
  1081.  
  1082. void make_sure_short(type)
  1083. int type;
  1084. {
  1085.  if (type == longtype) make_short();
  1086.  else
  1087.  if (type == singletype) { make_integer(type); make_short(); }
  1088.  else
  1089.  if (type == stringtype) _error(4);
  1090. }
  1091.  
  1092. void make_sure_long(type)
  1093. int type;
  1094. {
  1095.  if (type == shorttype) make_long();
  1096.  else
  1097.  if (type == singletype) make_integer(type);
  1098.  else
  1099.  if (type == stringtype) _error(4);
  1100. }
  1101.